package com.edu.webSocket;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.http.HttpServlet;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;

import com.edu.dao.BaseDao;
import com.edu.entity.ChartingRecords;
import com.edu.service.ChartingRecordsService;
import com.edu.service.impl.ChartingRecordsServiceImpl;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@ServerEndpoint(value = "/chat")
public class ChartingRecordswebSocket extends HttpServlet{
    // 使用线程安全的ConcurrentHashMap存储会话
    private static final Map<String, Session> userSessionMap = new ConcurrentHashMap<>(); // 用户名到会话的映射
    private static final ObjectMapper om = new ObjectMapper();
    private ChartingRecordsService crs = new ChartingRecordsServiceImpl();

    @OnOpen
    public void onOpen(Session session) {
        System.out.println("连接建立成功: " + session.getId());
        
        try {
            String query = session.getQueryString();
            if (query == null || query.isEmpty()) {
                closeSessionWithError(session, "缺少必要参数");
                return;
            }
            
            query = URLDecoder.decode(query, "UTF-8");
            Map<String, String> params = parseQueryString(query);
            String username = params.get("sendUsername");
            String reciveusername = params.get("reciveusername");
            
            if (username == null || reciveusername == null) {
                closeSessionWithError(session, "缺少用户名或接收者信息");
                return;
            }
            
            // 存储会话信息（使用用户名作为key）
            userSessionMap.put(username, session);
            System.out.println("用户连接: " + username + " 接收者: " + reciveusername);
            
        } catch (Exception e) {
            System.err.println("处理连接错误: " + e.getMessage());
            closeSession(session);
        }
    }

    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
        // 从map中移除当前会话 使用迭代器获取map对象中获得键对值 安全删除元素
    	// Map.Entry<String, Session> 是 Java 集合框架中的一个重要概念，它表示 Map 中的一个键值对
        Iterator<Map.Entry<String, Session>> iterator = userSessionMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Session> entry = iterator.next();
            if (entry.getValue().equals(session)) {
                iterator.remove();
//                System.out.println("移除用户: " + entry.getKey());
            }
        }
        closeSession(session);
    }

    public Session getSession(String username) {
        return userSessionMap.get(username);
    }

    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        System.out.println("接受信息" + message);
        // 解析消息
        ChartingRecords newcharting = om.readValue(message, ChartingRecords.class); 
        newcharting.setSend_at(new Date());
        // 存储到数据库
        boolean result = crs.addChartingRecords(newcharting);
        if (result) {
            System.out.println("成功插入数据库");
        } else {
            System.out.println("插入数据库失败");
        }
        
        // 同时发送给发送方和接收方
        String jsonMessage = om.writeValueAsString(newcharting);
        
        // 发送给接收方
        Session targetSession = getSession(newcharting.getReciveusername());
        if (targetSession != null && targetSession.isOpen()) {
            sendMessage(targetSession, jsonMessage);
        }
        
        // 新增：同时发送给发送方（自己）
        Session senderSession = getSession(newcharting.getSendUsername());
        if (senderSession != null && senderSession.isOpen()) {
            // 避免重复发送给同一个会话（当发送方和接收方相同时）
            if(!senderSession.equals(targetSession)) { 
                sendMessage(senderSession, jsonMessage);
            }
        }
    }

    @OnError
    public void onError(Session session, Throwable t) {
        t.printStackTrace();
        System.out.println("系统异常");
        closeSession(session);
    }

    // 发送消息到指定会话
    private void sendMessage(Session session, String message) {
        try {
            if (session != null && session.isOpen()) {
                session.getBasicRemote().sendText(message);
            }
        } catch (IOException e) {
            System.err.println("发送消息错误: " + e.getMessage());
            closeSession(session);
        }
    }

    // 解析查询字符串
    private Map<String, String> parseQueryString(String query) {
        Map<String, String> params = new HashMap<>();
        if (query != null && !query.isEmpty()) {
            String[] pairs = query.split("&");
            for (String pair : pairs) {
                int idx = pair.indexOf("=");
                if (idx > 0) {
                    String key = pair.substring(0, idx);
                    String value = pair.substring(idx + 1);
                    params.put(key, value);
                }
            }
        }
        return params;
    }
    
    // 关闭会话并处理错误
    private void closeSessionWithError(Session session, String errorMessage) {
        System.err.println(errorMessage);
        try {
            if (session.isOpen()) {
                session.close(new CloseReason(CloseReason.CloseCodes.VIOLATED_POLICY, errorMessage));
            }
        } catch (IOException e) {
            System.err.println("关闭会话错误: " + e.getMessage());
        }
    }
    
    // 安全关闭会话
    private void closeSession(Session session) {
        try {
            if (session != null && session.isOpen()) {
                session.close();
            }
        } catch (IOException e) {
            System.err.println("关闭会话错误: " + e.getMessage());
        }
    }
}